// VueRouter插件
let Vue;
import routerLink from "./components/router-link";
import routerView from "./components/router-view";
import createMatch from "./createMatch";

import { HashHistory } from "./history/hash";
import { HtmlHistory } from "./history/html5";

export default class VueRouter {
  constructor(options) {
    this.beforeHooks = [];
    this.match = createMatch(options.routes || []); // { addRoutes, match }
    options.mode = options.mode || 'hash';
    switch (options.mode) {
      case 'hash':
        this.history = new HashHistory(this);
        break;
      case 'history':
        this.history = new HtmlHistory(this);
        break;
    }
  }
  // 全局路由守卫
  beforeEach(cb) {
    this.beforeHooks.push(cb);
  }
  push(location) {
    this.history.push(location);
  }
  init(app) {
    // 获取到当前路由
    const history = this.history;
    // 跳转监听
    const setUpHashListener = () => {
      history.setUpHashListener();
    }
    history.listen(route => {
      app._route = route;
    })
    // 回调里面设置hashchange监听
    history.transitionTo(
      history.getCurrentLocation,
      setUpHashListener,
    );
  }
}

// 插件的安装方法(添加2个全局组件，将路由对象到_router上)
VueRouter.install = function(_Vue) {
  Vue = _Vue;
  Vue.component("router-link", routerLink);
  Vue.component("router-view", routerView);
  Vue.mixin({
    beforeCreate() {
      // this === Vue实例对象
      if (this.$options.router) {
        this._routerRoot = this;
        this._router = this.$options.router;
        this._router.init(this); // 初始化
        Vue.util.defineReactive(this, '_route', this._router.history.current);
      } else {
        this._routerRoot = this.$parent && this.$parent._routerRoot;
      }
    }
  })
  Object.defineProperty(Vue.prototype, '$router', {
    get() {
      return this._routerRoot._router;
    }
  })
  Object.defineProperty(Vue.prototype, '$route', {
    get() {
      return this._routerRoot._route;
    }
  })
}